package com.gopay.checkorder.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.NbcbConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.bank.nbcb.ebank.query.req.NbcbB2cReqList;
import com.gopay.common.domain.bank.nbcb.ebank.query.req.NbcbB2cReqNetPay;
import com.gopay.common.domain.bank.nbcb.ebank.query.res.NbcbB2cResList;
import com.gopay.common.domain.bank.nbcb.ebank.query.res.NbcbB2cResNetPay;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.util.TransUtil;
import com.gopay.remote.bank.BankInteractRemoteService;

public class CheckOrderNbcbB2cImpl implements BankOrderService  {
	
	private final static Logger logger = LoggerFactory.getLogger("NBCB");

	@Resource(name = "bankClient")
	private BankInteractRemoteService bankClient;
	@Override
	public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setSuccess(false);
		checkOrderResult.setOrderId(bankOrder.getOrderId());
		try {
			NbcbB2cReqNetPay message = new NbcbB2cReqNetPay();
			message.setBank(BankConstants.BANK_LOGO_NBCB);
			message.setBankOrderId(bankOrder.getOutOrderId());
		    message.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));
		    message.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));
			NbcbB2cReqList reqlist = new NbcbB2cReqList();
			reqlist.setInitOrderID(bankOrder.getOutOrderId());
			if(bankOrder.getSendBankTm()!=null){
				String orderDate = bankOrder.getSendBankTm().toString().replace("-", "");
				reqlist.setInitOrderDate(orderDate.substring(0,8));
			}else{
				String orderDate = bankOrder.getCreatedTs().toString().replace("-", "");
				reqlist.setInitOrderDate(orderDate.substring(0,8));
			}
			List list = new ArrayList<NbcbB2cReqList>();
			list.add(reqlist);
			message.setReq(list);
			Result result = new Result();
			message.setOrderId(bankOrder.getOrderId());
			result = bankClient.query(message);
			if (result == null || !result.isSuccess()
					|| result.getDefaultModel() == null) {
				logger.error("bankClient fail.");
				if(result ==null || ProcCodeConstants.PROC_CODE_100E6037.equals(result.getResultCode())){
					BankCountDownLatch.failIncrease(bankOrder.getBankCode());
					checkOrderResult.setCommunicateError(true);
				}
				logger.error(ToStringBuilder.reflectionToString(result,ToStringStyle.DEFAULT_STYLE));
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("系统返回对账结果为空");
				return checkOrderResult;
			}

			NbcbB2cResNetPay res = (NbcbB2cResNetPay) result.getDefaultModel();
			if (res == null) {
				// 查询订单为空
				logger.error("fail:orderId:" + bankOrder.getOrderId()+ " errcode:" + ProcCodeConstants.PROC_CODE_100E6022+ " err:bis query is null.");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("银行返回对账结果为空");
				return checkOrderResult;
			}

			List repList = res.getRep();
			NbcbB2cResList rep = new NbcbB2cResList();
			for(int i=0; i<repList.size(); i++){
				rep = (NbcbB2cResList)repList.get(i);
			}
			String orderStatus =rep.getTranResult(); // 交易状态
			//成功处理
			if (orderStatus.equals(NbcbConstants.ORDERSTATUS_SUCC)) {
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				logger.info("宁波银行B2C订单" + res.getOrderId() + "的交易成功");
				checkOrderResult.setErrMsg("银行返回交易成功");
				checkOrderResult.setSuccess(true);
				InAccInfo accInfo = new InAccInfo();
				accInfo.setOrderId(bankOrder.getOrderId());
				accInfo.setAmount(new BigDecimal(TransUtil.amountConvert2Yuan(rep.getOrderAmount())));
				accInfo.setRetCode("00");
				accInfo.setCardType(BankCardType.Unknown.toString());
				checkOrderResult.setAccInfo(accInfo);
			}
			//失败处理
			else if (orderStatus.equals(NbcbConstants.ORDERSTATUS_FAIL)) {
				checkOrderResult.setBankFailure(true);
				logger.info("宁波银行B2C订单" + res.getOrderId() + "的交易失败");
				checkOrderResult.setErrMsg("银行返回交易失败");
			}
			else if (orderStatus.equals(NbcbConstants.ORDERSTATUS_DOU) || orderStatus.equals(NbcbConstants.ORDERSTATUS_NOFLW) || orderStatus.equals(NbcbConstants.CHECK_FAIL)) {
				logger.info("宁波银行B2C订单" + res.getOrderId() + "的交易待银行确认");
		      checkOrderResult.setErrMsg("银行返回交易待确认");
			}else {
				logger.info("宁波银行B2C订单" + res.getOrderId() + "的交易发生未明情况");
				checkOrderResult.setErrMsg("银行返回交易未明情况");
			}
			
			return checkOrderResult;
		
		} catch (Exception e) {
			logger.error("bankClient fail.", e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("银行对账异常");
			return checkOrderResult;
		}
	}
	@Override
	public BankOrder getDbOrder() {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public BaseMessage dayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public List<CheckOrderResult> checkDayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result getDayendMsg(String string) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
		// TODO Auto-generated method stub
		return null;
	}
}

